package com.tanhua.dubbo.server.api;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.tanhua.dubbo.server.pojo.FreezingUser;
import com.tanhua.dubbo.server.pojo.UnFreezingUser;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.TimeUnit;

@Service(version = "1.0.0")
public class UserPageInfoApiImpl implements UserPageInfoApi {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String FREEZE_USER_REDIS_KEY_PREFIX = "FREEZE_USER";

    //封禁3天时间
    private static final Long FREEZE_TIME_3 = ( 10L);
    //封禁7天时间
    private static final Long FREEZE_TIME_7 = (3600L * 24L * 7L);

    @Autowired
    private MongoTemplate mongoTemplate;


    /**
     * 冻结用户
     *
     * @param userId
     * @param freezingTime       //     '冻结时间，1为冻结3天，2为冻结7天，3为永久冻结',
     * @param freezingRange      //    '冻结范围，1为冻结登录，2为冻结发言，3为冻结发布动态',
     * @param reasonsForFreezing //'冻结原因',
     * @param frozenRemarks      //    '冻结备注',
     * @return
     */
    @Override
    public String freezeUser(Integer userId, Integer freezingTime, Integer freezingRange,
                             String reasonsForFreezing, String frozenRemarks) {

        if (queryUserIsFreeze(userId)) {
            //已经是冻结中
            return null;
        }
        //还未冻结
        String redisKey = getFreezeUserRedisKeyPrefix(userId);

        FreezingUser freezingUser = new FreezingUser();
        freezingUser.setId(ObjectId.get());
        freezingUser.setUserId(userId);
        freezingUser.setFreezingTime(freezingTime);
        freezingUser.setFreezingRange(freezingRange);
        freezingUser.setReasonsForFreezing(reasonsForFreezing);
        freezingUser.setFrozenRemarks(frozenRemarks);
        freezingUser.setCreated(System.currentTimeMillis());
        String jsonStr = JSONUtil.toJsonStr(freezingUser);
        switch (freezingTime) {
            case 1: {
                redisTemplate.opsForValue().set(redisKey, jsonStr, 10, TimeUnit.SECONDS);
                break;
            }
            case 2: {
                redisTemplate.opsForValue().set(redisKey, jsonStr, 7, TimeUnit.DAYS);
                break;
            }
            case 3: {
                redisTemplate.opsForValue().set(redisKey, jsonStr);
                break;
            }
            default:
                return null;
        }
        mongoTemplate.save(freezingUser);
        return "冻结成功";
    }

    /**
     * 用户解冻操作
     *
     * @param userId
     * @param reasonsForThawing
     * @return
     */
    @Override
    public String unfreezeUser(Integer userId, String reasonsForThawing) {
        try {
            if (!queryUserIsFreeze(userId)) {
                //表示是未冻结,不需要解冻
                return null;
            }
            //表示不是冻结,需要解冻
            //先删除redis中的数据
            String redisKey = getFreezeUserRedisKeyPrefix(userId);
            redisTemplate.delete(redisKey);
            //再删除数据库中的数据
            Query query = Query.query(Criteria.where("userId").is(userId));
            mongoTemplate.remove(query, FreezingUser.class);
            //并将解冻消息记录
            UnFreezingUser unFreezingUser = new UnFreezingUser();
            unFreezingUser.setId(ObjectId.get());
            unFreezingUser.setUserId(userId);
            unFreezingUser.setReasonsForThawing(reasonsForThawing);
            unFreezingUser.setCreated(System.currentTimeMillis());
            mongoTemplate.save(unFreezingUser);
            return "解冻成功";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 查询该用户是否为封禁中
     *
     * @param userId
     * @return
     */
    public boolean queryUserIsFreeze(Integer userId) {
        //先去redis中查询
        String redisKey = getFreezeUserRedisKeyPrefix(userId);
        String data = redisTemplate.opsForValue().get(redisKey);
        if (ObjectUtil.isNotEmpty(data)) {
            //表示是被封禁中
            return true;
        }
        //保证数据完整性,再去mongodb中查询
        Query query = Query.query(Criteria.where("userId").is(userId));
        FreezingUser freezingUser = mongoTemplate.findOne(query, FreezingUser.class);
        if (ObjectUtil.isEmpty(freezingUser)) {
            //表示数据库也没有该用户的封禁消息
            return false;
        }
        //判断封禁的时长是否还在有效期内
        Integer freezingTime = freezingUser.getFreezingTime();
        if (freezingTime == 1) {
            //表示封禁时间为3天
            Long created = freezingUser.getCreated();
            //当前时间-封禁的时间>3天
            if ((System.currentTimeMillis() - created) > FREEZE_TIME_3) {
                //删除原有数据库中的数据冻结信息,
                mongoTemplate.remove(freezingUser);
                //并将解冻消息记录
                UnFreezingUser unFreezingUser = new UnFreezingUser();
                unFreezingUser.setId(ObjectId.get());
                unFreezingUser.setUserId(userId);
                unFreezingUser.setReasonsForThawing("封禁时效过期");
                unFreezingUser.setCreated(System.currentTimeMillis());
                mongoTemplate.save(unFreezingUser);
                return false;
            }
        } else if (freezingTime == 2) {
            //表示封禁时间为7天
            Long created = freezingUser.getCreated();
            //封禁的天数加上封禁时的时间如果大于当前时间表示已经过了时效
            if ((System.currentTimeMillis() - created) > FREEZE_TIME_7) {
                //删除原有数据库中的数据冻结信息,
                mongoTemplate.remove(freezingUser);
                //并将解冻消息记录
                UnFreezingUser unFreezingUser = new UnFreezingUser();
                unFreezingUser.setId(ObjectId.get());
                unFreezingUser.setUserId(userId);
                unFreezingUser.setReasonsForThawing("封禁时效过期");
                unFreezingUser.setCreated(System.currentTimeMillis());
                mongoTemplate.save(unFreezingUser);
                return false;
            }
        }
        //表示还在有效封禁期内
        return true;
    }

    /**
     * 查询用户的封禁范围
     *
     * @param userId
     * @return
     */
    @Override
    public Integer queryUserFreezingRange(Long userId) {
        //查询数据库是否有数据
        Query query = Query.query(Criteria.where("userId").is(userId));
        FreezingUser freezingUser = mongoTemplate.findOne(query, FreezingUser.class);
        if (ObjectUtil.isEmpty(freezingUser)) {
            //数据库没有表示确实没有
            return null;
        }
        //表示数据库中有,到redis中查询
        String redisKey = getFreezeUserRedisKeyPrefix(Convert.toInt(userId));
        String data = redisTemplate.opsForValue().get(redisKey);
        if (ObjectUtil.isNotEmpty(data)) {
            //表示redis中有数据
            return freezingUser.getFreezingRange();
        }
        //表示redis中已经没有数据(数据已过期)
        //删除数据库的数据
        mongoTemplate.remove(freezingUser);
        return null;
    }

    private String getFreezeUserRedisKeyPrefix(Integer uid) {
        return FREEZE_USER_REDIS_KEY_PREFIX + uid;
    }


}
